﻿using Controllers;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using MyProject;
using Newtonsoft.Json;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Security.Principal;
using System.Text;
using Util;

namespace Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class UserLoginController: BaseController
    {
        public IFreeSql _fsql;
        public UserLoginController(IFreeSql fsql)
        {
            _fsql = fsql;
        }
        //用户登录获取Token
        [HttpPost]
        [AllowAnonymous]//这个是开放接口不用认证，因为用户第一次登录没有Token
        public ApiModel GetToken([FromBody] UserLoginDto user)
        {
            if(string.IsNullOrWhiteSpace(user.Password) || string.IsNullOrWhiteSpace(user.Tel))
            {
                return apiModel(Status.Error, "账号或密码错误！");
            }
            var userinfo = _fsql.Select<Userinfo>().Where(a => a.Tel == user.Tel && a.Password == user.Password).First();
            if(userinfo == null)
            {
                return apiModel(Status.Error, "账号或密码错误！");
            }
            //生成token
            var token = CreatToken(JsonConvert.SerializeObject(userinfo),7*24*60);
            return apiModel(Status.Success, "", new {token = token});
        }





        #region 生成用户Token
        /// <summary>
        /// 生成token
        /// 前端传过来header里加入Authorization字段 ： Bearer 空格+token
        /// </summary>
        /// <param name="jsonStr">用户实体json</param>
        /// <param name="minutes">Token过期时间</param>
        /// <returns></returns>
        public string CreatToken(string jsonStr, int minutes)
        {
            var claim = new Claim[]
            {
                new Claim("user",jsonStr),//用户信息,可以选择部分用户信息存入，方便根据前端请求Token获取对应信息（json格式）
                new Claim(ClaimTypes.Role,"user")//角色
            };

            //密钥
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtSettings.IssuerSigningKey));
            //证书签名
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);

            //生成token
            var token = new JwtSecurityToken(JwtSettings.ValidIssuer//发布者
                                             , JwtSettings.ValidAudience//接收者
                                             , claim //用户信息角色信息
                                             , DateTime.Now//当前创建时间
                                             , DateTime.Now.AddMinutes(minutes)//过期时间
                                             , creds//证书签名
                                             );
            string tokenStr = new JwtSecurityTokenHandler().WriteToken(token);//写入token

            return tokenStr;//返回
        }
        #endregion
    }

    public class UserLoginDto
    {
        public string? Password { get; set; }
        public string? Tel { get; set; }
    }
}
